package com.echatim.controller.fileserver;


import com.annotation.Permission;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.broker.base.protocol.response.Resp;
import com.commom.Config;
import com.commom.LocalFileRespError;
import com.commom.LocalFileRoute;
import com.commom.PermissionConst;
import com.echatim.ApplicationWrapper;
import com.echatim.service.app.fileserver.FileInfoService;
import com.echatim.syslog.annotation.SysLog;
import com.utils.Beans;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 本地文件服务器接口
 *
 * @author Daizhiqiang
 * @date 2019/11/22 18:07
 */

@Api(value = "本地文件服务器", tags = "本地文件服务器")
@ConditionalOnProperty(name="echatim.sdk.auth-type", havingValue="community")
@RestController
@RequestMapping(LocalFileRoute.common.base)
@Slf4j
public class FileServerController extends ApiController {
    @Autowired
    private FileApi fileApi;
    @Autowired
    private FileInfoService fileInfoService;

    @Value("${echatim.file.sign-expire}")
    private String signatureExpireMs;

    /**
     *  WEB 直传, 获取上传凭证
     *
     * */
    @Permission(value = PermissionConst.ALL)
    @ApiOperation(value = "FILE直传-获取上传凭证")
    @SysLog("FILE直传-获取上传凭证")
    @CrossOrigin
    @PostMapping(LocalFileRoute.common.file.getUploadSign)
    public Resp<FileUploadRequestDTO> getUploadSign(@RequestBody @Validated FileUploadRequestForm form) {
        Resp<FileUploadRequestDTO> dto =  fileApi.createWebUploadSign(form, Long.parseLong(signatureExpireMs));
        FileSignatureCache.instance().putCache(dto.getData().getSignature(), Beans.copy(dto.getData(), FileUploadCacheDTO.class)
                .setFileName(form.getFileName())
                .setFileType(form.getFileType()));
        return dto;
    }

    /**
     *  WEB 直传, 上传
     *
     * */
    @Permission(value = PermissionConst.ALL)
    @ApiOperation(value = "WEB直传-上传")
    @SysLog("WEB直传-上传")
    @CrossOrigin
    @ResponseBody
    @RequestMapping(LocalFileRoute.common.file.upload)
    public Resp<Map<String, Object>> upload(HttpServletResponse response,
                                         @RequestParam("signature") String signature,
                                         @RequestParam("file") MultipartFile file) {
        response.setHeader("Access-Control-Allow-Origin", "*");
        if (file == null){
            return Resp.failed(LocalFileRespError.NOT_UPLOAD_FILE);
        }
        FileUploadCacheDTO cacheInfo = FileSignatureCache.instance().getCache(signature);
        if(cacheInfo == null || cacheInfo.getExpire() <= new Date().getTime()/1000){
            log.error("上传文件的signature:" + signature + "已过期, 或上传缓存已失效");
            return  Resp.failed(LocalFileRespError.SIGNATURE_EXPIRE_OR_CACHE_EXPIRE);
        }

        String lastFileName = cacheInfo.getDir();
        String path = Beans.strNotEmpty(Config.get(ApplicationWrapper.getContext(), "echatim.file.upload-file-dir")) ? Config.get(ApplicationWrapper.getContext(), "echatim.file.upload-file-dir") : "";
        String host = Beans.strNotEmpty(Config.get(ApplicationWrapper.getContext(), "echatim.file.host")) ? Config.get(ApplicationWrapper.getContext(), "echatim.file.host") : "http://localhost";
        if (!saveFile(file, lastFileName , path)){
            return  Resp.failed(LocalFileRespError.SAVE_UPLOAD_FILE);
        }
        String downUrl = "http://" + host +  LocalFileRoute.common.base +  LocalFileRoute.common.file.download + "/" + lastFileName;
        fileInfoService.saveOrUpdateFileInfo(new FileUploadCallbackForm()
                .setFilename(cacheInfo.getDir())
                .setFileType(cacheInfo.getFileType())
                .setSize(file.getSize()+"")
                .setOriginFileName(cacheInfo.getFileName())
                , "local"
                , cacheInfo.getSdkKey()
                , downUrl);

        return Resp.ok(new HashMap<String, Object>(){{
            put("url", downUrl);
        }});

    }



    /***
     * 保存文件
     * @param file
     * @return 文件上传是否成功
     */
    private boolean saveFile(MultipartFile file, String key, String path){
        String fileName = key.substring(key.lastIndexOf("/") + 1);
        String preDir = key.replace(fileName, "");
        String fileDirPath = path + File.separator + preDir;
        try {
            if (!new File(fileDirPath).exists()){
                new File(fileDirPath).mkdirs();
            }
            // 转存文件
            file.transferTo(new File(fileDirPath + fileName));
        } catch(Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }



}
